package com.northpool.operator.analysis.dataset;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.custom.DatasetParam;
import com.northpool.operator.type.TypeEnum;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.modules.geoprocess.operator.IPipelineOperator;
import com.northpool.stpclient.operator.bean.DatasetBean;
import com.northpool.stpclient.operator.bean.OperatorBean;
import com.northpool.stpclient.operator.bean.ParamBean;
import com.northpool.stpclient.operator.bean.PipelineBean;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

@OperatorInfo(
        ref = "PropsSplitOperator",
        name = "分割",
        description = "分割具有叠加要素的输入以创建输出要素类的子集。"
)
public class SpatialSplitOperator extends StpClientOperatorBase {
    String dataSourceIdA;
    String tableNameA;
    String spatialFieldA;
    String sqlFilterA;
    String dataSourceIdB;
    String tableNameB;
    String spatialFieldB;
    String sqlFilterB;
    String targetDataSourceId;

    String fields;
    String splitField;
    String tableNamePrefix;

    @InputParams({
            @InputParam(ref = "datasetA", name = "数据集A", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true),
            @InputParam(ref = "fields", name = "选择字段", desc = "数据字段列表，多个逗号隔开，如: f_id,dlmc,dlbm", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "spatialFieldA", name = "空间字段A", desc = "空间字段名称，如: geom", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "sqlFilterA", name = "SQL过滤条件A", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "datasetB", name = "数据集B", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true),
            @InputParam(ref = "spatialFieldB", name = "空间字段B", desc = "空间字段名称，如: geom", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "sqlFilterB", name = "SQL过滤条件B", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "splitField", name = "分割字段", desc = "分割字段名称", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "targetDataSourceId", name = "目标数据源ID", desc = "目标数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "tableNamePrefix", name = "目标数据集前缀", desc = "目标数据集前缀", type = TypeEnum.STRING, required = true)
    })
    public SpatialSplitOperator() {
        super();
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        DatasetParam datasetA = params.getDataset("datasetA");
        DatasetParam datasetB = params.getDataset("datasetB");

        this.dataSourceIdA = datasetA.getDataSourceId();
        this.tableNameA = datasetB.getTableName();
        this.fields = params.getStr("fields");
        this.spatialFieldA = params.getStr("spatialFieldA");
        this.sqlFilterA = params.getStr("sqlFilterA");
        this.dataSourceIdB = datasetB.getDataSourceId();
        this.tableNameB = datasetB.getTableName();
        this.spatialFieldB = params.getStr("spatialFieldB");
        this.sqlFilterB = params.getStr("sqlFilterB");

        this.splitField = params.getStr("splitField");
        this.targetDataSourceId = params.getStr("targetDataSourceId");
        this.tableNamePrefix = params.getStr("tableNamePrefix");

        PipelineBean pipeline = new PipelineBean();
        pipeline.setResultFile(System.getProperty("user.dir") + File.separator + "result_file");
        DatasetBean dataSet = new DatasetBean();
        dataSet.setDataSourceId(dataSourceIdA);
        dataSet.setTableName(tableNameA);
        dataSet.setFields(fields);
        dataSet.setSqlFilter(sqlFilterA);
        pipeline.setDataSet(dataSet);

        List<OperatorBean> ops = new LinkedList<>();
        ops.add(buildPgSink());

        pipeline.setOperators(ops);
        IPipelineOperator iPipelineOperator = this.client.pipelineOperator();
        BaseResponse response = iPipelineOperator.startPipeline(pipeline);
        iPipelineOperator.onStart(response.getRequestId(), () -> {
            this.log("分割开始");
        });
        iPipelineOperator.onSuccess(response.getRequestId(), () -> {
            this.log("分割成功");
            String log = iPipelineOperator.log(response.getRequestId());
            this.log(log);
            this.successExit();
        });
        iPipelineOperator.onError(response.getRequestId(), () -> {
            this.error("分割失败");
            String log = iPipelineOperator.log(response.getRequestId());
            this.error(log);
            this.failedExit();
        });
        this.waiting(24);
    }

    public OperatorBean buildPgSink() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.spatial.vector.SpatialSplitPgSink");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("dataSourceId", dataSourceIdB));
        params.add(new ParamBean("tableName", tableNameB));
        params.add(new ParamBean("sqlFilter", sqlFilterB));
        params.add(new ParamBean("spatialField", spatialFieldB));
        params.add(new ParamBean("splitField", splitField));
        params.add(new ParamBean("fields", fields));
        params.add(new ParamBean("targetDataSourceId", targetDataSourceId));
        params.add(new ParamBean("tableNamePrefix", tableNamePrefix));
        operatorBean.setStartParam(params);
        operatorBean.setParallelism(8);
        return operatorBean;
    }
}
